/**
 * 创建人:  @author huangpeng    
 * 创建时间:  2023年11月05日 17:17
 * 项目名称:  lemon-blog-cloud
 * 文件名称:  WebFileUtils
 * 文件描述:  @Description: 网络文件工具类
 * <p>
 * All rights Reserved, Designed By huangpeng 
 * @Copyright: 2021-2023
 *
 */
package com.lemon.common.core.utils.file;

import com.lemon.common.core.utils.primarykey.PrimaryKeyUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.net.ssl.*;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.file.Files;

/**
 * 包名称：com.lemon.common.core.utils.file
 * 类名称：WebFileUtils
 * 类描述：网络文件工具类
 * 创建人：@author huangpeng
 * 创建时间：2023年11月05日 17:17
 */
public class NetFileUtils {

    private static final Logger logger = LoggerFactory.getLogger(NetFileUtils.class);

    /**
     * 根据文件超链接地址获取远程读取文件
     * @Title: getNetUrl
     * @Description: 根据文件超链接地址获取远程读取文件
     * @param netUrl 文件超链接地址，支持http和https
     * @return: File
     * @throws:
     * @author: huangpeng
     * @Date: 2023/11/5 17:30
     */
    public static File getNetUrl(String netUrl) {
        //判断http和https
        File file = null;
        if (netUrl.startsWith("https://")) {
            file = getNetUrlHttps(netUrl);
        } else {
            file = getNetUrlHttp(netUrl);
        }
        return file;
    }

    /**
     * 通过http链接获取文件流
     * @Title: getNetUrlHttp
     * @Description: 通过http链接获取文件
     * @param netUrl http文件链接
     * @return: File
     * @throws:
     * @author: huangpeng
     * @Date: 2023/11/5 17:23
     */
    private static File getNetUrlHttp(String netUrl) {
        //对本地文件命名
        String fileName = reloadFile(netUrl);
        File file = null;
        URL urlfile;
        InputStream inStream = null;
        OutputStream os = null;
        try {
            file = File.createTempFile("net_url", fileName);
            //下载
            urlfile = new URL(netUrl);
            inStream = urlfile.openStream();
            os = Files.newOutputStream(file.toPath());

            int bytesRead = 0;
            byte[] buffer = new byte[8192];
            while ((bytesRead = inStream.read(buffer, 0, 8192)) != -1) {
                os.write(buffer, 0, bytesRead);
            }
        } catch (Exception e) {
            logger.error("远程图片获取错误："+netUrl, e);
        } finally {
            try {
                if (null != os) {
                    os.close();
                }
                if (null != inStream) {
                    inStream.close();
                }

            } catch (Exception e) {
                logger.error("获取http文件, 输出输入流关闭失败");
            }
        }
        return file;
    }

    /**
     * 通过https链接获取文件
     * @Title: getNetUrlHttps
     * @Description: 通过https链接获取文件
     * @param fileUrl https链接
     * @return: File
     * @throws:
     * @author: huangpeng
     * @Date: 2023/11/5 17:24
     */
    private static File getNetUrlHttps(String fileUrl) {
        //对本地文件进行命名
        String file_name = reloadFile(fileUrl);
        File file = null;

        DataInputStream in = null;
        DataOutputStream out = null;
        try {
            file = File.createTempFile("net_url", file_name);

            SSLContext sslcontext = SSLContext.getInstance("SSL", "SunJSSE");
            sslcontext.init(null, new TrustManager[]{new X509TrustUtiil()}, new java.security.SecureRandom());
            URL url = new URL(fileUrl);
            HostnameVerifier ignoreHostnameVerifier = new HostnameVerifier() {
                @Override
                public boolean verify(String s, SSLSession sslsession) {
                    logger.warn("WARNING: Hostname is not matched for cert.");
                    return true;
                }
            };
            HttpsURLConnection.setDefaultHostnameVerifier(ignoreHostnameVerifier);
            HttpsURLConnection.setDefaultSSLSocketFactory(sslcontext.getSocketFactory());
            HttpsURLConnection urlCon = (HttpsURLConnection) url.openConnection();
            urlCon.setConnectTimeout(6000);
            urlCon.setReadTimeout(6000);
            int code = urlCon.getResponseCode();
            if (code != HttpURLConnection.HTTP_OK) {
                throw new Exception("文件读取失败");
            }
            // 读文件流
            in = new DataInputStream(urlCon.getInputStream());
            out = new DataOutputStream(Files.newOutputStream(file.toPath()));
            byte[] buffer = new byte[2048];
            int count = 0;
            while ((count = in.read(buffer)) > 0) {
                out.write(buffer, 0, count);
            }
            out.close();
            in.close();
        } catch (Exception e) {
            logger.error("远程图片获取错误："+fileUrl, e);
        } finally {
            try {
                if (null != out) {
                    out.close();
                }
                if (null != in) {
                    in.close();
                }
            } catch (Exception e2) {
                logger.error("获取https文件,输出输入流关闭失败");
            }
        }
        return file;
    }

    /**
     * 重命名，UUIU
     * @Title: reloadFile
     * @Description: 重命名，UUIU
     * @param oleFileName 文件id
     * @return: String
     * @throws:
     * @author: huangpeng
     * @Date: 2023/11/5 17:27
     */
    private static String reloadFile(String oleFileName) {
        oleFileName = getFileName(oleFileName);
        if (StringUtils.isEmpty(oleFileName)) {
            return oleFileName;
        }
        //得到后缀
        if (!oleFileName.contains(".")) {
            //对于没有后缀的文件，直接返回重命名
            return PrimaryKeyUtils.generateId().toString();
        }
        String[] arr = oleFileName.split("\\.");
        // 根据uuid重命名图片
        return PrimaryKeyUtils.generateId().toString() + "." + arr[arr.length - 1];
    }

    /**
     * 把带路径的文件地址解析为真实文件名 /upload/hp/xxx.mp4 解析为 xxx.mp4
     * @Title: getFileName
     * @Description: 把带路径的文件地址解析为真实文件名 /upload/hp/xxx.mp4 解析为 xxx.mp4
     * @param url 文件地址
     * @return: String
     * @throws:
     * @author: huangpeng
     * @Date: 2023/11/5 17:28
     */
    public static String getFileName(final String url) {
        if (StringUtils.isEmpty(url)) {
            return url;
        }
        String newUrl = url;
        newUrl = newUrl.split("[?]")[0];
        String[] bb = newUrl.split("/");
        return bb[bb.length - 1];
    }
}
